<template>
	<view class="container">
		<!-- title -->
		<view class="title">
			<view class="title_left">
				<view class="name">{{ _t18(`price`) }}</view>
				<view class="unit">({{ coinInfo.baseCoinUpperCase }})</view>
			</view>
			<view class="title_right">
				<view class="name">{{ _t18('vol') }}</view>
				<view class="unit">
					({{
            coinInfo.customizeFlag === 2
              ? matchText(coinInfo.showSymbol, '/USDT')
              : coinInfo.coinUpperCase
          }})
				</view>
			</view>
		</view>

		<view class="leftList">
			<view class="itemList asks" v-show="showType.value != 2">
				<view class="item" v-for="(item, index) in rows" @click="emits('setTradePrice', asksList[index].price)"
					:key="`asks${index}`">
					<view class="fall fw-num">
						{{ asksList[index] && asksList[index].price ? priceFormat(asksList[index].price) : 0 }}</view>
					<view class="itemName fw-num">
						{{ asksList[index] && asksList[index].count ? countFormat(asksList[index].count) : 0}}</view>
					<view class="hightItem fall rfd-bg"
						:style="`width:${_toFixed(_mul(_div(asksList[index] && asksList[index].count ? asksList[index].count : 0, maxAskCount ?? 1), 100),2)}%;`">
					</view>
				</view>
			</view>
			<view class="itemCenter">
				<view :class="[
            _isRFD( tradeDetailInfo && tradeDetailInfo.open ? tradeDetailInfo.open : 0, tradeDetailInfo && tradeDetailInfo.close ? tradeDetailInfo.close : 0, 'buy', 'rise'),
            'fw-num centername'
          ]" @click="emits('setTradePrice', tradeDetailInfo && tradeDetailInfo.close ? tradeDetailInfo.close : 0)">
					{{ tradeDetailInfo && tradeDetailInfo.close ? priceFormat(tradeDetailInfo.close) : 0 }}
				</view>
				<view class="">≈${{ tradeDetailInfo && tradeDetailInfo.close ? tradeDetailInfo.close : 0 }}</view>
			</view>
			<view class="itemList" v-show="showType.value != 1">
				<view class="item itemHight" v-for="(item, index) in rows" :key="`bids${index}`"
					@click="emits('setTradePrice', bidsList[index] && bidsList[index].price ? bidsList[index].price : 0 )">
					<view class="rise fw-num">
						{{ bidsList[index] && bidsList[index].price ? priceFormat(bidsList[index].price) : 0  }}</view>
					<view class="itemName fw-num">
						{{ bidsList[index] && bidsList[index].count ? countFormat(bidsList[index].count) : 0  }}</view>
					<view class="hightItem rise rfd-bg"
						:style="`width:${_toFixed(_mul(_div(bidsList[index] && bidsList[index].count ? bidsList[index].count : 0, maxBidCount ?? 1), 100),2)}%;`">
					</view>
				</view>
			</view>
		</view>
		<view class="leftBottom">
			<view class="bottomLeft" @click="showDepthPopup = true">
				<view class="fw-num">{{ showDepth.label }}</view>
				<svg-load name="jiantou10x5-x" class="img"></svg-load>
			</view>
			<view class="bottomRight" @click="showTypePopup = true">
				<svg-load :name="showType.icon" class="img"></svg-load>
			</view>
		</view>
		<PublicPopup :show="showDepthPopup" @handelClose="showDepthPopup = false" :direction="`bottom`"
			:showHeader="false" :empty="false">
			<template #emptyContentCustomize>
				<view class="bbList">
					<view class="item" v-for="item in showDepthList" :key="item.value"
						:style="showDepth.label === item.label ? 'color:var(--ex-font-color2)' : ''"
						@click="_checkedShowDepth(item)">
						{{ item.label }}
					</view>
				</view>
			</template>
		</PublicPopup>
		<PublicPopup :show="showTypePopup" @handelClose="showTypePopup = false" :direction="`bottom`"
			:showHeader="false" :empty="false">
			<template #emptyContentCustomize>
				<view class="bbList">
					<view class="item" v-for="item in showTypeList" :key="item.value"
						:style="showType.value === item.value ? 'color:var(--ex-font-color2)' : ''"
						@click="_checkedShowType(item)">
						{{ item.label }}
					</view>
				</view>
			</template>
		</PublicPopup>
	</view>
</template>

<script setup>
	import PublicPopup from '@/components/Popup/public.vue'
	import {
		socketDict
	} from '@/config/dict'
	import PubSub from 'pubsub-js'
	import {
		_add,
		_sub,
		_div,
		_toFixed,
		_mul,
		countFormat,
		priceFormat
	} from '@/utils/decimal'
	import _ from 'lodash'
	import {
		_t18
	} from '@/utils/public'
	import {
		useTradeStore
	} from '@/store/trade'
	import {
		watch,
		computed,
	reactive,
	ref,
	onMounted,
	onUnmounted
	} from 'vue'
	import {
		matchText
	} from '@/utils/filters'
	import { getSpontaneousCoinOrderBookApi } from '@/api/spontaneous'

	const emits = defineEmits(['setTradePrice'])
	const props = defineProps({
		coinInfo: {
			type: Object
		},
		/**
		 * 行数 最大30 默认4
		 */
		rows: {
			type: Number,
			default: 4
		}
	})
	/**
	 * 盘口显示类型
	 */
	const showTypeList = [
		// 默认
		{
			label: _t18(`bb_default`),
			value: 0,
			icon: 'morenpan'
		},
		// 卖出盘
		{
			label: _t18(`bb_sell_order`),
			value: 1,
			icon: 'maichupan'
		},
		// 买入盘
		{
			label: _t18(`bb_buy_order`),
			value: 2,
			icon: 'mairupan'
		}
	]
	/**
	 * 当前显示类型
	 */
	const showType = ref(showTypeList[0])
	/**
	 * 显示Popup变量
	 */
	const showTypePopup = ref(false)
	/**
	 * 显示行数
	 */
	const rows = computed(() => (showType.value.value != 0 ? props.rows * 2 : props.rows))
	/**
	 * 选中盘口显示类型
	 */
	const _checkedShowType = (item) => {
		if (item.value != showType.value.value) {
			showType.value = item
		}
		showTypePopup.value = false
	}
	/**
	 * 盘口显示类型
	 */
	const showDepthListDict = [{
			label: '0.00000001',
			value: 0,
			min: 0.00000001
		},
		{
			label: '0.0000001',
			value: 1,
			min: 0.0000001
		},
		{
			label: '0.000001',
			value: 2,
			min: 0.000001
		},
		{
			label: '0.00001',
			value: 3,
			min: 0.00001
		},
		{
			label: '0.0001',
			value: 4,
			min: 0.0001
		},
		{
			label: '0.001',
			value: 5,
			min: 0.001
		},
		{
			label: '0.01',
			value: 6,
			min: 0.01
		},
		{
			label: '0.1',
			value: 7,
			min: 0.1
		},
		{
			label: '1',
			value: 8,
			min: 10
		},
		{
			label: '10',
			value: 9,
			min: 100
		},
		{
			label: '100',
			value: 10,
			min: 1000
		}
	]
	const showDepthList = ref([])
	/**
	 * 当前显示类型
	 */
	const showDepth = reactive({})

	/**
	 * 显示Popup变量
	 */
	const showDepthPopup = ref(false)
	/**
	 * 选中盘口显示类型
	 */
	const _checkedShowDepth = (item) => {
		if (item.value != showDepth.value) {
			Object.assign(showDepth, item)
		}
		showDepthPopup.value = false
	}

	// 最大卖出数量
	const maxAskCount = ref(0)
	// 最大买入数量
	const maxBidCount = ref(0)
	/**
	 * 买入列表
	 */
	const bidsList = reactive([])
	/**
	 * 卖出列表
	 */
	const asksList = reactive([])
	
	// 更新状态管理
	const isUpdating = ref(false)
	const lastUpdateTime = ref(0)
	const updateThrottleTime = 500 // 最小更新间隔500ms

	// 生成 区间 随机整数
	const getRandomInteger = (min, max) => {
		return Math.floor(Math.random() * (max - min + 1)) + min
	}
	/**
	 * 获取最小单位值
	 */
	function getIntegerPart(number) {
		var integerPart = Math.floor(number) // 获取整数部分
		let temp = Math.pow(10, integerPart.toString().length - 1)
		if (integerPart < 10) {
			temp = Math.pow(10, 5 - number.toString().split('.')[1]?.length)
		}
		return temp
	}
	/**
	 * 判断是否为币种
	 * @param {Object} coinInfo 币种信息
	 * @returns {boolean}
	 */
	const isSpontaneousCoin = (coinInfo) => {
		return coinInfo && (coinInfo.market === 'spontaneous' || coinInfo.spontaneousCoin === true)
	}

	/**
	 * 对比订单簿数据是否发生变化
	 * @param {Array} oldData 旧数据
	 * @param {Array} newData 新数据
	 * @returns {boolean} 是否有变化
	 */
	const compareOrderBookData = (oldData, newData) => {
		if (!oldData || !newData || oldData.length !== newData.length) {
			return true
		}
		
		for (let i = 0; i < oldData.length; i++) {
			const oldItem = oldData[i]
			const newItem = newData[i]
			
			if (!oldItem || !newItem) {
				return true
			}
			
			// 比较价格和数量
			if (oldItem.price !== newItem.price || oldItem.count !== newItem.count) {
				return true
			}
		}
		
		return false
	}

	/**
	 * 检查是否可以更新（防抖机制）
	 * @returns {boolean}
	 */
	const canUpdate = () => {
		const now = Date.now()
		if (isUpdating.value || (now - lastUpdateTime.value) < updateThrottleTime) {
			return false
		}
		return true
	}

	/**
	 * 获取币种真实订单簿数据
	 */
	const getSpontaneousCoinOrderBook = async () => {
		try {
			if (!props.coinInfo?.coin || !canUpdate()) {
				return
			}

			isUpdating.value = true
			lastUpdateTime.value = Date.now()

			const response = await getSpontaneousCoinOrderBookApi(props.coinInfo.coin, props.rows * 2)
			if (response && response.code === 200) {
				const orderBook = response.data
				
				// 处理买单数据（bids）
				const bidsData = orderBook.bids || []
				const tempBidsList = bidsData.map(item => ({
					price: parseFloat(item.price),
					count: parseFloat(item.count)
				}))

				// 处理卖单数据（asks）
				const asksData = orderBook.asks || []
				const tempAsksList = asksData.map(item => ({
					price: parseFloat(item.price),
					count: parseFloat(item.count)
				}))

				// 检查数据是否有变化
				const bidsChanged = compareOrderBookData(bidsList, tempBidsList)
				const asksChanged = compareOrderBookData(asksList, tempAsksList)
				
				// 计算最大数量用于显示比例
				maxBidCount.value = Math.max(...tempBidsList.map(e => e.count), 0)
				maxAskCount.value = Math.max(...tempAsksList.map(e => e.count), 0)
				
				// 更新数据：使用 splice 替换所有元素
				if (bidsChanged) {
					bidsList.splice(0, bidsList.length, ...tempBidsList)
				}
				if (asksChanged) {
					asksList.splice(0, asksList.length, ...tempAsksList)
				}
				
				console.log('币种订单簿数据更新:', props.coinInfo.coin, {
					bidsCount: tempBidsList.length,
					asksCount: tempAsksList.length,
					bidsChanged,
					asksChanged
				})
			}
		} catch (error) {
			console.error('获取币种订单簿失败:', error)
			// 如果获取失败，回退到模拟数据
			getMockDataList()
		} finally {
			isUpdating.value = false
		}
	}

	/**
	 * 根据当前价格随机成交量
	 */
	const getMockDataList = () => {
		setTimeout(getMockDataListThrottle, getRandomInteger(900, 1600))

		let price = tradeDetailInfo.value?.close
		let coefficient = 1 / getIntegerPart(price)
		let aggregationFactor = showDepth?.min
		let countFactor = aggregationFactor * 1000
		if (price < 1000) {
			countFactor = aggregationFactor * 10 ** (`${price}`.length - 1)
		}

		if (!price || !Number(aggregationFactor)) {
			maxAskCount.value = 0
			maxBidCount.value = 0
			// 清空列表
			const emptyData = Array.from({ length: props.rows * 2 }, () => ({
				price: 0,
				count: 0
			}))
			Object.assign(asksList, emptyData)
			Object.assign(bidsList, emptyData)
			return
		}
		// 生成数量 大 -> 小
		let tempAsksList = []
		let tempBidsList = []
		let hashCount = _mul(_mul(Math.random(), coefficient), countFactor)
		if (price < 10) {
			hashCount = _mul(_mul(Math.random(), coefficient), countFactor)
		}

		for (let i = 1; i <= props.rows * 2; i++) {
			let randomCount = _mul(Math.random(), hashCount) + _mul(Math.random(), coefficient)
			let tempObj = {
				price: _add(_add(price, i * aggregationFactor), 0),
				count: randomCount
			}
			tempAsksList.push(tempObj)
			tempAsksList = tempAsksList.sort((a, b) => a.price - b.price)
		}

		for (let i = 1; i <= props.rows * 2; i++) {
			let randomCount = _mul(Math.random(), hashCount) + _mul(Math.random(), coefficient)

			let tempObj = {
				price: _sub(_sub(price, i * aggregationFactor), 0),
				count: randomCount
			}
			tempBidsList.push(tempObj)
			tempBidsList = tempBidsList.sort((a, b) => b.price - a.price)
		}
		maxAskCount.value = Math.max(...tempAsksList.filter((e, i) => i < props.rows).map((e) => e.count))
		maxBidCount.value = Math.max(...tempBidsList.filter((e, i) => i < props.rows).map((e) => e.count))
		Object.assign(asksList, tempAsksList)
		Object.assign(bidsList, tempBidsList)
	}
	/**
	 * 交易详情数据
	 */
	const tradeStore = useTradeStore()
	const tradeDetailInfo = computed(() => tradeStore.allCoinPriceInfo[props.coinInfo?.coin])
	
	
	watch(
		() => props.coinInfo?.coin,
		() => {
			console.log('币种更换', props.coinInfo?.coin, props.rows, tradeDetailInfo.value.close)
			
			// 切换币种时清空订单簿数据并重置更新状态
			bidsList.splice(0, bidsList.length)
			asksList.splice(0, asksList.length)
			maxBidCount.value = 0
			maxAskCount.value = 0
			isUpdating.value = false
			lastUpdateTime.value = 0
			
			if (tradeDetailInfo.value?.close > 0) {
				showDepthList.value = showDepthListDict
					.filter((elem) => elem.min * 30 < tradeDetailInfo.value.close)
					.slice(-4)
				Object.assign(showDepth, showDepthList.value[0])
				
				// 根据币种类型选择数据获取方式
				if (isSpontaneousCoin(props.coinInfo)) {
					// 币种直接获取真实数据
					getSpontaneousCoinOrderBook()
				} else {
					// 普通币种使用模拟数据
					getMockDataListThrottle()
				}
			}
		}
	)

	/**
	 * 更新数据 限流
	 */
	const getMockDataListThrottle = _.throttle(() => {
		if (isSpontaneousCoin(props.coinInfo)) {
			// 如果是币种，获取真实订单簿数据
			getSpontaneousCoinOrderBook()
		} else {
			// 如果是普通币种，使用模拟数据
			getMockDataList()
		}
	}, 2000) // 增加节流时间到2秒，减少频繁更新

	const subKey = PubSub.subscribe(socketDict.DETAIL, (key, data) => {
		if (data.symbol && data.symbol == props.coinInfo.coin) {
			if (tradeDetailInfo.value.close && showDepthList.value.length) {
				// 根据币种类型选择数据获取方式
				if (isSpontaneousCoin(props.coinInfo)) {
					// 币种获取真实订单簿数据，使用防抖机制
					if (canUpdate()) {
						getSpontaneousCoinOrderBook()
					}
				} else {
					// 普通币种使用模拟数据
					getMockDataListThrottle()
				}
			} else {
				showDepthList.value = showDepthListDict
					.filter((elem) => elem.min * 30 < tradeDetailInfo.value.close)
					.slice(-4)
				Object.assign(showDepth, showDepthList.value[0])
				
				// 根据币种类型选择数据获取方式
				if (isSpontaneousCoin(props.coinInfo)) {
					if (canUpdate()) {
						getSpontaneousCoinOrderBook()
					}
				} else {
					getMockDataList()
				}
			}
		}
	})

	/**
	 * 初始化订单簿数据
	 */
	const initOrderBook = () => {
		if (!tradeDetailInfo.value?.close || !props.coinInfo?.coin) {
			console.log('价格或币种信息未就绪，跳过初始化')
			return
		}
		
		console.log('开始初始化订单簿，币种:', props.coinInfo.coin, '价格:', tradeDetailInfo.value.close)
		
		// 设置显示深度列表
		showDepthList.value = showDepthListDict
			.filter((elem) => elem.min * 30 < tradeDetailInfo.value.close)
			.slice(-4)
		
		if (showDepthList.value.length > 0 && !showDepth.value) {
			Object.assign(showDepth, showDepthList.value[0])
		}
		
		// 根据币种类型选择数据获取方式
		if (isSpontaneousCoin(props.coinInfo)) {
			console.log('币初始化，获取订单簿数据')
			getSpontaneousCoinOrderBook()
		} else {
			console.log('普通币种初始化，生成模拟数据')
			getMockDataListThrottle()
		}
	}

	/**
	 * 组件挂载时初始化数据
	 */
	onMounted(() => {
		console.log('Handicap 组件挂载', props.coinInfo?.coin)
		initOrderBook()
	})
	
	/**
	 * 监听价格数据变化，如果初始加载时价格未就绪，等价格准备好后再加载
	 */
	watch(
		() => tradeDetailInfo.value?.close,
		(newPrice) => {
			if (newPrice > 0 && bidsList.length === 0 && asksList.length === 0) {
				console.log('价格数据已准备，触发订单簿初始化')
				initOrderBook()
			}
		}
	)

	onUnmounted(() => {
		subKey && PubSub.unsubscribe(subKey)
	})
</script>

<style lang="scss" scoped>
	.title {
		display: flex;
		justify-content: space-between;
		font-size: 12px;
		color: var(--ex-passive-font-color);

		.title_left {
			text-align: left;
		}

		.title_right {
			text-align: right;
		}

		.unit {
			margin-top: 2px;
		}
	}

	.leftList {
		height: 82%;
		margin-top: 12px;
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: space-between;

		.itemList {
			display: flex;
			flex-direction: column;
			justify-content: space-between;

			&.asks {
				flex-direction: column-reverse;
				/* 水平反转主轴方向 */
			}

			.item {
				overflow: hidden;
				font-size: 12px;
				color: var(--ex-font-color2);
				display: flex;
				align-items: center;
				justify-content: space-between;
				height: 20px;
				position: relative;
				z-index: 2;
				margin-bottom: 4px;
				padding: 0 5px;

				.itemName {
					color: var(--ex-default-font-color);
				}

				.hightItem {
					transition: 0.5s;
					right: 0;
					position: absolute;
					height: 20px;
					min-width: 2%;
					z-index: -1;
				}
			}
		}

		.itemCenter {
			text-align: center;
			font-size: 12px;
			color: var(--ex-passive-font-color);
			padding: 12px 0;

			.centername {
				color: var(--ex-default-font-color);
				font-size: 16px;
				margin-bottom: 3px;
			}
		}
	}

	.leftBottom {
		margin-top: 20px;
		display: flex;
		justify-content: space-between;

		.bottomLeft {
			display: flex;
			padding: 0 10px;
			justify-content: space-between;
			align-items: center;
			width: 118px;
			height: 25px;
			background: var(--ex-view-bgColor);
			border-radius: 2px;
			font-size: 12px;
			font-weight: 500;
			color: var(--ex-default-font-color);

			.img {
				width: 10px;
				height: 5px;
			}
		}

		.bottomRight {
			display: flex;
			justify-content: center;
			align-items: center;
			width: 27px;
			height: 25px;
			background: var(--ex-view-bgColor);
			border-radius: 2px;

			.img {
				width: 15px;
				height: 15px;
			}
		}
	}

	// 选择BB
	.bbList {
		text-align: center;
    display: flex
;
    flex-direction: column;
		.item {
			// color:var(--ex-font-color2);
			color: var(--ex-default-font-color);
			font-size: 14px;
			padding: 20px 0;
			border-bottom: 1px solid var(--ex-border-color5);
		}

		.item:last-child {
			border-bottom: none;
		}
	}
</style>